package com.zhihuishu.micro.course.openapi.cc.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;

import com.zhihuishu.micro.course.dto.ChapterDto;
import com.zhihuishu.micro.course.openapi.cc.ChapterLessonOpenService;
import com.zhihuishu.micro.course.openapi.cc.dto.ChapterWebDto;
import com.zhihuishu.micro.course.openapi.cc.dto.LessonVideoWebDto;
import com.zhihuishu.micro.course.openapi.cc.dto.LessonWebDto;
import com.zhihuishu.micro.course.service.ChapterService;
import com.zhihuishu.micro.course.service.LessonService;
import com.zhihuishu.micro.course.service.LessonVideoService;
import com.zhihuishu.remote.RemoteException;
import com.zhihuishu.remote.RemoteResult;
import com.zhihuishu.toolkit.jedis.JedisHelper;
import com.zhihuishu.toolkit.jedis.JedisHelper.Handler;
import com.zhihuishu.toolkit.jedis.template.JedisExecutor;

@Service("chapterLessonOpenServiceForCC")
public class ChapterLessonOpenServiceImpl implements ChapterLessonOpenService {

    @Resource
    private JedisExecutor jedisExecutor;

    @Resource
    private ChapterService chapterService;

    @Resource
    private LessonService lessonService;

    @Resource
    private LessonVideoService lessonVideoService;

    @Override
    public RemoteResult<List<ChapterWebDto>> queryChapterBasicInfos(final long courseId)
            throws RemoteException {
        RemoteResult<List<ChapterWebDto>> result = new RemoteResult<List<ChapterWebDto>>();
        final List<ChapterWebDto> chapters = new ArrayList<ChapterWebDto>();
        jedisExecutor.execute( new Handler() {
            @Override
            public void handle(Jedis jedis) {
                // 根据课程ID，获取章列表
                Set<String> chapterIds = jedis.smembers(JedisHelper.key("cc:course", courseId, "chapters"));
                // 根据课程ID，获取节列表
                Set<String> lessonIds = jedis.smembers(JedisHelper.key("cc:course", courseId, "lessons"));
                // 根据课程ID，获取小节列表
                Set<String> lvIds = jedis.smembers(JedisHelper.key("cc:course", courseId, "lvs"));

                // 使用管道获取数据
                Pipeline pip = jedis.pipelined();
                // 获取章数据
                if (!CollectionUtils.isEmpty(chapterIds))
                    for (String chapterId : chapterIds) {
                        if (chapterId == null)
                            continue;
                        pip.hmget(JedisHelper.key("cc:chapter", chapterId), "id", "name", "rank", "courseId");
                    }
                // 获取节数据
                if (!CollectionUtils.isEmpty(lessonIds))
                    for (String lessonId : lessonIds) {
                        if (lessonId == null)
                            continue;
                        pip.hmget(JedisHelper.key("cc:lesson", lessonId), "id", "name", "rank", "chapterId");
                    }
                // 获取小节数据
                if (!CollectionUtils.isEmpty(lvIds))
                    for (String lvId : lvIds) {
                        if (lvId == null)
                            continue;
                        pip.hmget(JedisHelper.key("cc:lv", lvId), "id", "name", "rank", "lessonId");
                    }
                // 提取结果
                List<Object> result = pip.syncAndReturnAll();
                if (CollectionUtils.isEmpty(result))
                    return;
                List<LessonWebDto> lessons = new ArrayList<LessonWebDto>();
                List<LessonVideoWebDto> lvs = new ArrayList<LessonVideoWebDto>();
                for (int i = 0, len = result.size(); i < len; i++) {
                    Object obj = result.get(i);
                    if (i < chapterIds.size()) {
                        ChapterWebDto chapter = toChapter(obj);
                        if (chapter != null && chapter.getId() != null)
                            chapters.add(chapter);
                    } else if (i < chapterIds.size() + lessonIds.size()) {
                        LessonWebDto lesson = toLesson(obj);
                        if (lesson != null && lesson.getId() != null && lesson.getChapterId() != null)
                            lessons.add(lesson);
                    } else {
                        LessonVideoWebDto lv = toLessonVideo(obj);
                        if (lv != null && lv.getId() != null && lv.getLessonId() != null)
                            lvs.add(lv);
                    }
                }
                if (CollectionUtils.isEmpty(chapters))
                    return;

                // 组合数据
                // 如果小节列表不为空，将小节写入到节中
                if (!CollectionUtils.isEmpty(lvs)) {
                    // 小节列表排序
                    Collections.sort(lvs, new Comparator<LessonVideoWebDto>() {
                        @Override
                        public int compare(LessonVideoWebDto o1, LessonVideoWebDto o2) {
                            if (o1 == null || o2 == null)
                                return 0;
                            return o1.getRank().compareTo(o2.getRank());
                        }
                    });
                    // 组合数据
                    for (LessonWebDto lesson : lessons) {
                        for (LessonVideoWebDto lv : lvs) {
                            if (lv.getLessonId().equals(lesson.getId())) {
                                if (lesson.getLessonVideos() == null) {
                                    lesson.setLessonVideos(new ArrayList<LessonVideoWebDto>());
                                }
                                lesson.getLessonVideos().add(lv);
                            }
                        }
                    }
                }
                // 如果节列表不为空，将节写入到章中
                if (!CollectionUtils.isEmpty(lessons)) {
                    // 小节列表排序
                    Collections.sort(lessons, new Comparator<LessonWebDto>() {
                        @Override
                        public int compare(LessonWebDto o1, LessonWebDto o2) {
                            if (o1 == null || o2 == null)
                                return 0;
                            return o1.getRank().compareTo(o2.getRank());
                        }
                    });
                    // 组合数据
                    for (ChapterWebDto cwd : chapters) {
                        for (LessonWebDto lesson : lessons) {
                            if (lesson == null || lesson.getId() == null)
                                continue;
                            if (cwd.getId().equals(lesson.getChapterId())) {
                                if (cwd.getLessons() == null)
                                    cwd.setLessons(new ArrayList<LessonWebDto>());
                                cwd.getLessons().add(lesson);
                            }
                        }
                    }
                }
            }
        });
        if (!CollectionUtils.isEmpty(chapters)) {
            result.setResult(chapters);
        }
        return result;
    }

    /**
     * 从Redis获取的数据转换为小节对象
     * 
     * @param obj
     * @return
     */
    private LessonVideoWebDto toLessonVideo(Object obj) {
        if (obj == null)
            return null;
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) obj;
        LessonVideoWebDto lvw = new LessonVideoWebDto();
        if (list.get(0) != null)
            lvw.setId(NumberUtils.toInt(list.get(0).toString()));
        if (list.get(1) != null)
            lvw.setName(list.get(1).toString());
        if (list.get(2) != null)
            lvw.setRank(NumberUtils.toInt(list.get(2).toString()));
        if (list.get(3) != null)
            lvw.setLessonId(NumberUtils.toInt(list.get(3).toString()));
        return lvw;
    }

    /**
     * 从Redis获取的数据转换为章对象
     * 
     * @param obj
     * @return
     */
    private ChapterWebDto toChapter(Object obj) {
        if (obj == null)
            return null;
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) obj;
        ChapterWebDto cwd = new ChapterWebDto();
        if (list.get(0) != null)
            cwd.setId(NumberUtils.toInt(list.get(0).toString()));
        if (list.get(1) != null)
            cwd.setName(list.get(1).toString());
        if (list.get(2) != null)
            cwd.setRank(NumberUtils.toInt(list.get(2).toString()));
        if (list.get(3) != null)
            cwd.setCourseId(NumberUtils.toInt(list.get(3).toString()));
        return cwd;
    }

    /**
     * 从Redis获取的数据转换为节对象
     * 
     * @param obj
     * @return
     */
    private LessonWebDto toLesson(Object obj) {
        if (obj == null)
            return null;
        @SuppressWarnings("unchecked")
        List<String> list = (List<String>) obj;
        LessonWebDto lwd = new LessonWebDto();
        if (list.get(0) != null)
            lwd.setId(NumberUtils.toInt(list.get(0).toString()));
        if (list.get(1) != null)
            lwd.setName(list.get(1).toString());
        if (list.get(2) != null)
            lwd.setRank(NumberUtils.toInt(list.get(2).toString()));
        if (list.get(3) != null)
            lwd.setChapterId(NumberUtils.toInt(list.get(3).toString()));
        return lwd;
    }

    @Override
    public RemoteResult<Void> updateChapterRedis(int chapterId) throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            chapterService.touchChapter(chapterId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> updateLessonRedis(int lessonId) throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonService.touchLesson(lessonId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> updateLessonVideoRedis(int lessonVideoId) throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonVideoService.touchLessonVideo(lessonVideoId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> addChapterOnCourseRedis(final long courseId, final int chapterId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        ChapterDto dto = chapterService.get(chapterId);
        try {
            if (dto != null && dto.getIsPass() != null && dto.getIsPass().equals(1)) {
                chapterService.addChapterOnCourseRedis(courseId, chapterId);
            }
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> addChapterOnCourseRedisWithOutChecPassStatus(long courseId, int chapterId) {
        RemoteResult<Void> remoteResult=new RemoteResult<Void>();
        try {
            chapterService.addChapterOnCourseRedisWithOutChecPassStatus(courseId,chapterId);
        } catch (Exception e) {
            remoteResult.setExceptionStack(e);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<Void> removeChapterOnCourseRedis(final long courseId, final int chapterId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            chapterService.removeChapterOnCourseRedis(courseId, chapterId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> addLessonOnCourseRedis(final long courseId, final int lessonId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonService.addLessonOnCourseRedis(courseId, lessonId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> removeLessonOnCourseRedis(final long courseId, final int lessonId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonService.removeLessonOnCourseRedis(courseId, lessonId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }
    
    @Override
    public RemoteResult<Void> removeChapterOnCourseRedisWithOutChecPassStatus(long courseId, int chapterId) {
        RemoteResult<Void> remoteResult = new RemoteResult<Void>();
        try {
            chapterService.removeChapterOnCourseRedisWithOutChecPassStatus(courseId, chapterId);
        } catch (Exception e) {
            remoteResult.setExceptionStack(e);
        }
        return remoteResult;
    }

    @Override
    public RemoteResult<Void> addLessonVideoOnCourseRedis(final long courseId, final int lessonVideoId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonVideoService.addLessonVideoOnCourseRedis(courseId, lessonVideoId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

    @Override
    public RemoteResult<Void> removeLessonVideoOnCourseRedis(final long courseId, final int lessonVideoId)
            throws RemoteException {
        RemoteResult<Void> r = new RemoteResult<Void>();
        try {
            lessonVideoService.removeLessonVideoOnCourseRedis(courseId, lessonVideoId);
        } catch (Exception e) {
            r.setExceptionStack(e);
        }
        return r;
    }

   

}
